<template>
  <div
    class="pull-refresh"
    ref="scrollBox"
    @touchstart="touchStart"
    @touchmove="touchMove"
    @touchend="touchEnd"
  >
    <div class="pull-refreshing-box" :style="style" v-if="this.moveDistance > 0">
      <div v-if="moveState < 2">
        <img src="../assets/images/base/loading-more.gif" alt />
      </div>
      <div v-else>
        <img src="../assets/images/base/loading-more.gif" alt />
      </div>
    </div>
    <div class="pull-present-box">
      <slot />
    </div>
  </div>
</template>

<script>
export default {
  name: 'PullRefresh',
  props: ['scroll'],
  data() {
    return {
      startY: '',
      moveDistance: 0,
      moveState: 0,
      duration: 0,
      refreshing: false
    }
  },
  computed: {
    style() {
      return {
        transition: `${this.duration}ms`,
        transform: `translate3d(0,${this.moveDistance}px, 0)`
      }
    }
  },
  methods: {
    touchStart(e) {
      this.duration = 0
      this.moveDistance = 0
      this.startY = e.targetTouches[0].clientY
    },
    touchMove(e) {
      const scrollTop = this.scroll ? document.getElementById(this.scroll).scrollTop : 0 || document.documentElement.scrollTop || document.body.scrollTop
      if (scrollTop > 0) return

      const move = e.targetTouches[0].clientY - this.startY
      if (move > 0) {
        e.preventDefault()
        this.moveDistance = Math.pow(move, 0.8)
        if (this.moveDistance > 50) {
          if (this.moveState === 1) return
          this.moveState = 1
          this.refreshing = true
        } else {
          if (this.moveState === 0) return
          this.moveState = 0
          this.refreshing = false
        }
      }
    },
    touchEnd(e) {
      this.duration = 300
      if (this.moveDistance > 50) {
        this.moveState = 2
        this.moveDistance = 80
        this.$emit('refresh', () => {
          this.moveState = 0
          this.refreshing = false
        })
      } else {
        this.moveDistance = 0
      }
    }
  },
  watch: {
    moveState(state) {
      if (state === 0 && this.duration === 300) {
        this.moveDistance = 0
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.pull-refresh {
  display: flex;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  flex-direction: column;
  .pull-refreshing-box {
    line-height: 50px;
    height: 50px;
    font-size: 14px;
    color: #fff;
    text-align: center;
    position: fixed;
    left: 0;
    right: 0;
    top: -50px;
    z-index: 9999;
    background: transparent;
    img {
      width: 44px;
      height: 44px;
    }
  }
  .pull-present-box {
    width: 100%;
    height: 100%;
    position: relative;
  }
}
</style>

